package br.edu.ifrn.dao;

import java.util.List;

import javax.persistence.Query;

import br.edu.ifrn.dominio.Curso;
import br.edu.ifrn.dominio.Diretoria;
import br.edu.ifrn.dominio.Perfil;
import br.edu.ifrn.dominio.Usuario;
import br.edu.ifrn.exception.NegocioException;
import br.edu.ifrn.generic.GenericDAO;

public class UsuarioDAO extends GenericDAO<Usuario>{
	
	public UsuarioDAO() {
		super();
	}

	@SuppressWarnings("unchecked")
	public List<Usuario> recuperarPorPerfil(Perfil perfil) {
		Query q = this.em.createQuery(
				"SELECT usuario FROM Usuario usuario  WHERE usuario.perfil = :perfil  ORDER BY usuario.nome"
				);
		q.setParameter("perfil", perfil);
		return q.getResultList();
	}
	@SuppressWarnings("unchecked")
	public List<Usuario> recuperarPorPerfil(Perfil perfil1, Perfil perfil2, Diretoria diretoria) {
		Query q = this.em.createQuery(
				"SELECT usuario FROM Usuario usuario  WHERE (usuario.perfil = :perfil1 OR usuario.perfil = :perfil2) AND usuario.diretoria = :diretoria ORDER BY usuario.nome"
				);
		q.setParameter("perfil1", perfil1);
		q.setParameter("perfil2", perfil2);
		q.setParameter("diretoria", diretoria);
		return q.getResultList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Usuario> recuperarPorPerfilFiltrados(Perfil perfil1, Perfil perfil2, Diretoria diretoria, String nome) {
		Query q = this.em.createQuery(
				"SELECT usuario FROM Usuario usuario  WHERE (usuario.perfil = :perfil1 OR usuario.perfil = :perfil2) AND usuario.diretoria = :diretoria" +
				" AND UPPER(usuario.nome) like :nome ORDER BY usuario.nome"
				);
		q.setParameter("perfil1", perfil1);
		q.setParameter("perfil2", perfil2);
		q.setParameter("diretoria", diretoria);
		q.setParameter("nome", "%"+nome.toUpperCase()+"%");
		return q.getResultList();
	}
	
	@Override
	public void beforeInsert(Usuario u)  throws Exception{
		if(u.isDiretor()){
			this.removerDiretor(u.getDiretoria());
		}
	}
	@Override
	public void afterInsert(Usuario u)  throws Exception{
		if(u.isDiretor()){
			this.adicionarDiretor(u.getDiretoria(), u);
		}
	}
	
	@Override
	public void beforeUpdate(Usuario u)  throws Exception{
		if(u.isDiretor()){
			this.removerDiretor(u.getDiretoria());
		}
		this.atualizarCoordenadoria(u);
	}
	@Override
	public void afterUpdate(Usuario u)  throws Exception{
		if(u.isDiretor()){
			this.adicionarDiretor(u.getDiretoria(), u);
		}
	}
	
	private void atualizarCoordenadoria(Usuario u) throws NegocioException {
		if(!u.isCoordenador()){
			 Usuario usuarioAntes = new UsuarioDAO().consultarPorId(u.getId());
			 if(usuarioAntes.isCoordenador()){
				 //ERA COORDENADOR
				for (Curso curso : usuarioAntes.getCursosCordenados()) {
					curso.setCoordenador(null);
					this.em.merge(curso);
				}
			 }
		}
	}
	
	
	private void removerDiretor(Diretoria diretoria) throws NegocioException {
		 DiretoriaDAO diretoriaDAO = new DiretoriaDAO();
		 Diretoria d = diretoriaDAO.consultarPorId(diretoria.getId());	
		 
		 Usuario diretorAnterior = d.getDiretor();
		 if(diretorAnterior!=null){
			 diretorAnterior.setPerfil(Perfil.Professor);
			 this.em.merge(diretorAnterior);
		 }
		 d.setDiretor(null);
		 this.em.merge(d);
	}
	private void adicionarDiretor(Diretoria diretoria, Usuario u) throws NegocioException {
		 DiretoriaDAO diretoriaDAO = new DiretoriaDAO();
		 Diretoria d = diretoriaDAO.consultarPorId(diretoria.getId());	
		 d.setDiretor(u);
		 this.em.merge(d);
	}
}
